package cc.mrbird.febs.business.service.impl;

import cc.mrbird.febs.accounting.dto.detailCost.TreeDTO;
import cc.mrbird.febs.business.entity.Business;
import cc.mrbird.febs.accounting.entity.StandardSubExtra;
import cc.mrbird.febs.business.mapper.BusinessMapper;
import cc.mrbird.febs.business.service.IBusinessService;
import cc.mrbird.febs.accounting.service.IStandardSubExtraService;
import cc.mrbird.febs.common.utils.FebsUtil;
import cc.mrbird.febs.business.entity.BusinessModule;
import cc.mrbird.febs.business.service.IBusinessModuleService;
import cc.mrbird.febs.utils.CodeConstant;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

@Service
public class BusinessServiceImpl extends ServiceImpl<BusinessMapper, Business> implements IBusinessService {

    @Resource
    private IStandardSubExtraService standardSubExtraService;
    @Resource
    private IBusinessModuleService businessModuleService;

    @Override
    public Boolean add(Business business) {
        business.setName(business.getName().trim());
        LambdaQueryWrapper<Business> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Business::getFatherId, business.getFatherId() > 0L ? business.getFatherId() : 0L);
        queryWrapper.eq(Business::getName, business.getName());
        queryWrapper.eq(Business::getType, business.getType());
        int res = this.baseMapper.selectCount(queryWrapper);
        if (res > 0) {
            return false;
        } else {
            if (business.getFatherId() < 0) {
                business.setModuleId(-1 * business.getFatherId());
                business.setFatherId(0L);
            }
            business.setCreateBy(FebsUtil.getCurrentUser().getUsername());
            business.setStandardMain(CodeConstant.incomeCode);
            business.setCode(UUID.randomUUID().toString().replaceAll("-",""));
            if (business.getType() == 5) {
                business.setOrder(201);
            } else {
                business.setOrder(401);
            }
            this.save(business);
            return true;
        }
    }

    @Override
    public Boolean update(Business business) {
        business.setName(business.getName().trim());
        LambdaQueryWrapper<Business> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Business::getFatherId, business.getFatherId() > 0L ? business.getFatherId() : 0L);
        queryWrapper.eq(Business::getName, business.getName());
        queryWrapper.eq(Business::getType, business.getType());
        queryWrapper.ne(Business::getId, business.getId());
        int res = this.baseMapper.selectCount(queryWrapper);
        if (res > 0) {
            return false;
        } else {
            Business newBusiness = this.getById(business.getId());
            newBusiness.setModifyBy(FebsUtil.getCurrentUser().getUsername());
            newBusiness.setModuleId(business.getModuleId());
            newBusiness.setName(business.getName());
            this.saveOrUpdate(business);
            return true;
        }
    }

    @Override
    public Boolean remove(Business business) {
        List<TreeDTO> tree = getBusinessTree(business.getType().toString());
        TreeDTO node = getNodeById(tree.get(0), business.getId());
        List<String> ids = new ArrayList<>();
        queryNode(node, ids);
        LambdaQueryWrapper<StandardSubExtra> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(StandardSubExtra::getBusinessId, ids);
        int res = standardSubExtraService.getBaseMapper().selectCount(queryWrapper);
        if (res > 0) {
            return false;
        } else {
            this.removeByIds(ids);
            return true;
        }
    }

    /*
     * @Author HBH
     * @Description 获取树选择框数据
     * @Date 2022/7/5
     **/
    @Override
    public List<TreeDTO> listTreeData(String type) {
        LambdaQueryWrapper<Business> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Business::getType, type);
        List<Business> list = this.baseMapper.selectList(queryWrapper);
        TreeDTO fNode = new TreeDTO();
        fNode.setId(0L);
        fNode.setName("业务线");
        fNode.setTitle("业务线");
        for (Business business : list) {
            TreeDTO node = new TreeDTO();
            node.setId(business.getId());
            node.setName(business.getName());
            node.setTitle(business.getName());
            node.setData(JSON.parseObject(JSON.toJSONString(business)));
            node.setCode(business.getCode());
            node.setParentId(business.getFatherId());
            getNode(fNode, node);
        }
        return fNode.getChildren();
    };

    /*
     * @Author HBH
     * @Description 获取业务树
     * @Date 2022/7/5
     **/
    @Override
    public List<TreeDTO> treeData(String type, String name) {
        TreeDTO fNode = getBusinessTree(type).get(0);
        if (name != null) {
            setFlag(fNode, name);
            removeNode(fNode);
        }
        List<TreeDTO> res = new ArrayList<>();
        LambdaQueryWrapper<BusinessModule> q2 = new LambdaQueryWrapper<>();
        List<BusinessModule> businessModuleList = businessModuleService.getBaseMapper().selectList(q2);

        for (BusinessModule businessModule : businessModuleList) {
            TreeDTO node = new TreeDTO();
            node.setTitle(businessModule.getModuleName());
            node.setName(businessModule.getModuleName());
            node.setId(-1 * businessModule.getId());
            for (TreeDTO child : fNode.getChildren()) {
                if (child.getModuleId().equals(businessModule.getId())) {
                    node.getChildren().add(child);
                }
            }
            res.add(node);
        }
        return res;
    }
    
    /*
     * @Author HBH
     * @Description 获取业务线树(不包括业务模块)
     * @Date 2022/7/5
     **/
    private List<TreeDTO> getBusinessTree(String type) {
        LambdaQueryWrapper<Business> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Business::getType, type);
        List<Business> list = this.baseMapper.selectList(queryWrapper);
        TreeDTO fNode = new TreeDTO();
        fNode.setId(0L);
        fNode.setName("业务线");
        fNode.setTitle("业务线");
        for (Business business : list) {
            TreeDTO node = new TreeDTO();
            node.setId(business.getId());
            node.setModuleId(business.getModuleId());
            node.setName(business.getName());
            node.setTitle(business.getName());
            node.setData(JSON.parseObject(JSON.toJSONString(business)));
            node.setCode(business.getCode());
            node.setParentId(business.getFatherId());
            getNode(fNode, node);
        }
        List<TreeDTO> res = new ArrayList<>();
        res.add(fNode);
        return res;
    }
    
    /*
     * @Author HBH
     * @Description 生成业务树
     * @Date 2022/7/5
     **/
    private void getNode(TreeDTO node, TreeDTO childNode) {
        if (node.getId().equals(childNode.getParentId())) {
            childNode.setParentId(node.getId());
            childNode.setHasParent(true);
            node.getChildren().add(childNode);
            node.setHasChild(true);
        } else {
            for (TreeDTO child : node.getChildren()) {
                getNode(child, childNode);
            }
        }
    }

    /*
     * @Author HBH
     * @Description 通过id获取树节点
     * @Date 2022/7/5
     **/
    private TreeDTO getNodeById(TreeDTO node, Long id) {
        if (node.getId().equals(id)) {
            return node;
        } else {
            for (TreeDTO child : node.getChildren()) {
                TreeDTO res = getNodeById(child, id);
                if (res != null) {
                    return res;
                }
            }
            return null;
        }
    }

    /*
     * @Author HBH
     * @Description 获取树节点路径的全部id
     * @Date 2022/7/5
     **/
    private void queryNode(TreeDTO node, List<String> ids) {
        ids.add(node.getId().toString());
        for (TreeDTO child : node.getChildren()) {
            queryNode(child, ids);
        }
    }

    /*
     * @Author HBH
     * @Description 为树节点添加标记（模糊查询用）
     * @Date 2022/7/5
     **/
    private void setFlag(TreeDTO node, String key) {
        node.setFlag(getFlag(node, key));
        for (TreeDTO child : node.getChildren()) {
            setFlag(child,key);
        }
    }

    /*
     * @Author HBH
     * @Description 获取树节点的标记，如果该节点或者其子节点中包含查询的key才标记为true
     * @Date 2022/7/5
     **/
    private Boolean getFlag(TreeDTO treeDTO, String key) {
        if (treeDTO.getName().contains(key)) {
            return true;
        } else {
            for (TreeDTO child : treeDTO.getChildren()) {
                Boolean res = getFlag(child, key);
                if (res != null) {
                    return res;
                }
            }
            return null;
        }
    }

    /*
     * @Author HBH
     * @Description 删除树中没有标记的节点(模糊查询用)
     * @Date 2022/7/5
     **/
    private void removeNode(TreeDTO treeDTO) {
        treeDTO.getChildren().removeIf(child -> child.getFlag() == null || !child.getFlag());
        for (TreeDTO child : treeDTO.getChildren()) {
            removeNode(child);
        }
    }
}
